﻿// Programmer: JR Padfield
// Description: 
// Version: 1
// Date: 

﻿using System;
using System.Collections.Generic;
using TheWorldLibrary.Skills;
using TheWorldLibrary.Spells;
using TheWorldLibrary.Talents;
using TheWorldLibrary.Effects;
using TheWorldLibrary.Sprites;

namespace TheWorldLibrary.Characters
{
    public enum EntityGender { Male, Female, Unknown }
    public enum EntityType { Character, NPC, Monster, Creature }

    public sealed class Entity
    {
        #region Entity Vital, Map, Sprite Field and Property Region

        private string entityName;
        private int entitySpriteNum;
        private int entityMap;
        private AnimationKey enitityDir;
        private bool inGame;

        private string entityClass;
        private EntityType entityType;
        private EntityGender entityGender;

        public string EntityName
        {
            get { return entityName; }
            set { entityName = value; }
        }

        public int EntitySpriteNum
        {
            get { return entitySpriteNum; }
            set { entitySpriteNum = value; }
        }

        public int EntityMap
        {
            get { return entityMap; }
            set { entityMap = value; }
        }

        public AnimationKey EntityDir
        {
            get { return enitityDir; }
            set { enitityDir = value; }
        }

        public bool InGame
        {
            get { return inGame; }
            set { inGame = value; }
        }

        public string EntityClass
        {
            get { return entityClass; }
            set { entityClass = value; }
        }

        public EntityType EntityType
        {
            get { return entityType; }
            set { entityType = value; }
        }

        public EntityGender EnitityGender
        {
            get { return entityGender; }
            set { entityGender = value; }
        }



        #endregion

        #region Skill Field and Property Region

        public Dictionary<string, Skill> Skills;
        public List<Modifier> SkillModifiers;

        #endregion

        #region Spell Field and Property Region

        public Dictionary<string, Spell> Spells;
        public List<Modifier> SpellModifiers;

        #endregion

        #region Talent Field and Property Region

        public Dictionary<string, Talent> Talents;
        public List<Modifier> TalentModifiers;

        #endregion

        #region Basic Attribute and Property Region

        private int strength;
        private int dexterity;
        private int cunning;
        private int willpower;
        private int magic;
        private int constitution;

        private int strengthModifier;
        private int dexterityModifier;
        private int cunningModifier;
        private int willpowerModifier;
        private int magicModifier;
        private int constitutionModifier;

        public int Strength
        {
            get { return strength + strengthModifier; }
            private set { strength = value; }
        }

        public int Dexterity
        {
            get { return dexterity + dexterityModifier; }
            private set { dexterity = value; }
        }

        public int Cunning
        {
            get { return cunning + cunningModifier; }
            private set { cunning = value; }
        }


        public int Willpower
        {
            get { return willpower + willpowerModifier; }
            private set { willpower = value; }
        }

        public int Magic
        {
            get { return magic + magicModifier; }
            private set { magic = value; }
        }

        public int Constitution
        {
            get { return constitution + constitutionModifier; }
            private set { constitution = value; }
        }

        #endregion

        #region Calculated Attribute Field and Property Region

        private AttributePair health;
        private AttributePair stamina;
        private AttributePair mana;

        public AttributePair Health
        {
            get { return health; }
        }

        public AttributePair Stamina
        {
            get { return stamina; }
        }

        public AttributePair Mana
        {
            get { return mana; }
        }

        private int attack;
        private int damage;
        private int defense;

        #endregion

        #region Resistance and Weakness Field and Property Region

        public List<Resistance> Resistances;

        public List<Weakness> Weaknesses;

        #endregion

        #region Level Field and Property Region

        private int level;
        private long experience;

        public int Level
        {
            get { return level; }
            private set { level = value; }
        }

        public long Experience
        {
            get { return experience; }
            private set { experience = value; }
        }

        #endregion

        #region Constructor Region

        /// <summary>
        /// Basic Entity
        /// </summary>
        public Entity()
        {            
        }

        /// <summary>
        /// NPC Entity
        /// </summary>
        /// <param name="name"></param>
        /// <param name="entityData"></param>
        /// <param name="gender"></param>
        /// <param name="entityType"></param>
        public Entity(
            string name,
            EntityData entityData,
            EntityGender gender,
            EntityType entityType)
        {
            EntityName = name;
            EntityClass = entityData.EntityName;
            EnitityGender = gender;
            EntityType = entityType;

            Strength = entityData.Strength;
            Dexterity = entityData.Dexterity;
            Cunning = entityData.Cunning;
            Willpower = entityData.Willpower;
            Magic = entityData.Magic;
            Constitution = entityData.Constitution;

            health = new AttributePair(0);
            stamina = new AttributePair(0);
            mana = new AttributePair(0);

            health = new AttributePair(0);
            stamina = new AttributePair(0);
            mana = new AttributePair(0);

            Skills = new Dictionary<string, Skill>();
            Spells = new Dictionary<string, Spell>();
            Talents = new Dictionary<string, Talent>();

            SkillModifiers = new List<Modifier>();
            SpellModifiers = new List<Modifier>();
            TalentModifiers = new List<Modifier>();

            Resistances = new List<Resistance>();
            Weaknesses = new List<Weakness>();
        }

        /// <summary>
        /// Playerable Character Entity
        /// </summary>
        /// <param name="name">Player's Name</param>
        /// <param name="sprite">Player's Sprite</param>
        /// <param name="entityData">Player's Vital/Class Information</param>
        /// <param name="gender">Player's Gender</param>
        /// <param name="entitytype">Player's Type: Default to character</param>
        /// <param name="map">Player's Map</param>
        public Entity(string name, int sprite, EntityData entityData, EntityGender gender, EntityType entitytype = EntityType.Character, int map = 0, AnimationKey key = AnimationKey.Down)
        {
            EntityName = name;
            EntitySpriteNum = sprite;
            EntityMap = map;
            EntityDir = key;
            EntityClass = entityData.EntityName;
            EnitityGender = gender;
            EntityType = entityType;
            InGame = false;


            Strength = entityData.Strength;
            Dexterity = entityData.Dexterity;
            Cunning = entityData.Cunning;
            Willpower = entityData.Willpower;
            Magic = entityData.Magic;
            Constitution = entityData.Constitution;

            health = new AttributePair(0);
            stamina = new AttributePair(0);
            mana = new AttributePair(0);

            Skills = new Dictionary<string, Skill>();
            Spells = new Dictionary<string, Spell>();
            Talents = new Dictionary<string, Talent>();

            SkillModifiers = new List<Modifier>();
            SpellModifiers = new List<Modifier>();
            TalentModifiers = new List<Modifier>();

            Resistances = new List<Resistance>();
            Weaknesses = new List<Weakness>();
        }

        #endregion

        #region Method Region

        public void Update(TimeSpan elapsedTime)
        {
            foreach (Modifier modifier in SkillModifiers)
                modifier.Update(elapsedTime);

            foreach (Modifier modifier in SpellModifiers)
                modifier.Update(elapsedTime);

            foreach (Modifier modifier in TalentModifiers)
                modifier.Update(elapsedTime);
        }

        #endregion
    }
}

